package com.qianfeng.openapi.zuul.filter;

import com.alibaba.fastjson.JSON;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import com.qianfeng.openapi.zuul.exception.ExceptionDict;
import com.qianfeng.openapi.zuul.exception.GatewayException;
import com.qianfeng.openapi.zuul.feign.CacheServiceClient;
import com.qianfeng.openapi.zuul.utils.Md5Util;
import com.qianfeng.openapi.zuul.utils.SysConstant;
import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;

/**
 * @Description:
 * @Company: 千锋互联
 * @Author: 李丽婷
 * @Date: 2021/1/4
 * @Time: 上午11:12
 */
@Component
public class SignFilter  extends ZuulFilter {

    @Resource
    private CacheServiceClient cacheServiceClient;


    @Override
    public String filterType() {
        return FilterConstants.PRE_TYPE;
    }

    @Override
    public int filterOrder() {
        return 1;
    }

    @Override
    public boolean shouldFilter() {
        return RequestContext.getCurrentContext().sendZuulResponse();
    }

    @Override
    public Object run() throws ZuulException {
        //1.请求上下文对象
        RequestContext context = RequestContext.getCurrentContext();
        //2.得到请求对象
        HttpServletRequest request = context.getRequest();
        //3.先得到签名
        String sign = request.getParameter(SysConstant.SIGN);
        //4.根据用户传入的参数（除了 签名外sign） method  appKey  token timestamp  利用加密算法得到签名
        Map<String,String> parameterMap  = getRequestParam(request);
        //5.得到参与加密的秘钥
        //﻿APPKEY:561AC1A8676CFCB0CC61B041AE42ABB8
        String appKey = request.getParameter(SysConstant.APPKEY);
        Map<String,String> map =  cacheServiceClient.hgetall(SysConstant.CACHE_﻿APPKEY+appKey);
        if (map==null||map.size()==0){
            throw  new GatewayException(ExceptionDict.ERROR_PARAM, "appKey参数错误");
        }
        String limit = map.get(SysConstant.LIMIT);
        //把limit存储到上下文中  (LimitFilter中需要用)
        context.set(SysConstant.LIMIT,limit);

        String appSecret=map.get(SysConstant.APP_SECRECT);
        System.out.println("sign="+sign+"----->"+appSecret);
        //得到计算的签名
        String md5Sign = Md5Util.md5Signature(parameterMap,appSecret);

        System.out.println("sign="+sign+"----md5sign="+md5Sign);
        if (!sign.equals(md5Sign)){
            context.setSendZuulResponse(false);
            context.getResponse().setContentType("application/json;charset=utf-8");
            context.setResponseStatusCode(HttpStatus.BAD_REQUEST.value());
            Map<String,Object> map1 = new HashMap<>();
            map1.put("code",ExceptionDict.SIGNATURERROR);//错误码
            map1.put("msg","签名错误");//错误信息

            String json = JSON.toJSONString(map1);

            context.setResponseBody(json);
        }

        return null;
    }

    /**
     * 得到除签名外的所有参数的值
     * @param request
     */
    private Map<String,String> getRequestParam(HttpServletRequest request) {
        // 1 != 1+n(n>1)
        //所有key
        Enumeration<String> enumeration =  request.getParameterNames();
        Map<String,String> parameterMap = new HashMap<>();
        while(enumeration.hasMoreElements()){
            String  key = enumeration.nextElement();
            if (!key.equals(SysConstant.SIGN)){//排除签名
                parameterMap.put(key,request.getParameter(key)+"");
            }
        }

        return  parameterMap;
    }


}
